package com.ruoyi.outpatient.service.patient.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.PatientConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.outpatient.core.LoginPatient;
import com.ruoyi.outpatient.domain.PatientCase;
import com.ruoyi.outpatient.domain.PatientIdentity;
import com.ruoyi.outpatient.mapper.patient.PatientRegMapper;
import com.ruoyi.outpatient.service.patient.IPatientRegService;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 *患者信息处理业务类
 */
@Service
public class PatientRegServiceImpl implements IPatientRegService {

    @Autowired
    private PatientRegMapper patientRegMapper;


    /**
     * 认证注入
     */
    @Autowired
    private AuthenticationManager authenticationManager;

    // token工具类注入
    @Autowired
    private PatientTokenService tokenService;

    // redis工具类
    @Autowired
    private RedisCache redisCache;

    /**
     * 插入患者身份证信息
     * @param identityCard 身份证号
     * @param patientName 患者名字
     * @return int
     */
    @Override
    public PatientIdentity insertPatientIdentity(String identityCard, String patientName) {

//        设置容量8的诊疗卡号
        StringBuffer buffer=new StringBuffer(8);

//        获取身份证号后四位作为诊疗卡号
        for (int i=identityCard.length()-4;i<identityCard.length();i++)
        {
            buffer.append(identityCard.charAt(i));
        }
//        获取随机四位进行拼接成诊疗卡
        buffer.append(RandomUtil.randomNumbers(4));

        PatientIdentity identity=new PatientIdentity();
        identity.setIdentityCard(identityCard);
        identity.setPatientName(patientName);
        identity.setMedicalCard(buffer.toString());
//        设置一个默认密码并加密存储
        identity.setMedicalPassword(SecurityUtils.encryptPassword(Constants.DEFAULT_PASSWROD));
        identity.setCreateTime(DateUtils.getNowDate());



//        将用户身份证等信息插入数据库
        int row=patientRegMapper.insertIdentity(identity);
        if (row==1){
//            将用户的诊疗卡和默认密码返回给患者
            identity.setIdentityCard(null); //将之前插入设为空,不给患者
            identity.setPatientName(null);
            identity.setMedicalPassword(Constants.DEFAULT_PASSWROD);

            return identity;
        }

        return null;

    }


    /**
     *  患者登录认证
     * @param medicalCard 诊疗号
     * @param medicalPassword 诊疗卡密码
     */
    @Override
    public String patientLogin(String medicalCard, String medicalPassword) {


//            将诊疗卡号和密码放入容器中
            UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(medicalCard,medicalPassword);
//            并交给认证进行管理
            Authentication authentication=authenticationManager.authenticate(authenticationToken);

            if (StringUtils.isNull(authentication))
            {
                throw new UserPasswordNotMatchException();
            }

//            获取容器用户信息,构成token存进redis
            Object principal = authentication.getPrincipal();
            LoginPatient loginPatient=(LoginPatient) principal;




//            获取token存进redis
            String token = tokenService.createToken(loginPatient);
//            设置redis的token键
            loginPatient.setToken(token);
//            tokenID作为将，用户信息作为值存到redis，并设置过期时间600分钟
            redisCache.setCacheObject(PatientConstants.PATIENT_TOKEN_KEY +loginPatient.getToken(), loginPatient, PatientConstants.Expire_Time, TimeUnit.MINUTES);

            return token;

    }
}
